package com.sc.nft.task;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import com.sc.nft.dao.CollectiveOrderDao;
import com.sc.nft.dao.SecondEquityPropsOrderDao;
import com.sc.nft.dao.SecondOrderDao;
import com.sc.nft.dao.TradingPoolOrderDao;
import com.sc.nft.entity.*;
import com.sc.nft.enums.PayChannelEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.service.*;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
@Slf4j
public class OrderTask {

    private final OrderService orderService;
    private final NewSecondCollectionCommonService newSecondCollectionCommonService;
    private final SecondOrderDao secondOrderDao;
    private final CollectiveOrderDao collectiveOrderDao;
    private final SecondOrderService secondOrderService;
    private final RoughStoneOrderService roughStoneOrderService;
    private final SecondEquityPropsOrderDao secondEquityPropsOrderDao;
    private final SecondEquityPropsOrderService secondEquityPropsOrderService;
    private final BusinessCardOrderService businessCardOrderDao;
    private final CollectiveOrderService  collectiveOrderService ;
    private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    private final ScOrderSettleService orderSettleService;
    private final TradingPoolOrderDao tradingPoolOrderDao;

    @XxlJob("closeOrder")
    public void closeOrder() throws Exception {
        orderService.getCloseOrder().forEach(order -> {
            try {
                orderService.autoCloseOrder(order);
            } catch (GlobalException e) {
                log.error("关闭订单异常 orderId:{}", order.getId(), e);
            }
        });
        //原石订单
        roughStoneOrderService.getCloseOrder().forEach(order -> {
            try {
                roughStoneOrderService.autoCloseOrder(order);
            } catch (GlobalException e) {
                log.error("关闭原石订单异常 orderId:{}", order.getId(), e);
            }
        });

        businessCardOrderDao.getCloseOrder().forEach(order ->{

            try {
                businessCardOrderDao.autoCloseOrder(order);
            } catch (GlobalException e) {
                log.error("关闭名片订单异常 orderId:{}", order.getId(), e);
            }
        });
    }



    /**
     * 关闭超时订单
     *
     * @throws Exception
     */
    @XxlJob("closeTimeOutOrder")
    public void closeTimeOutOrder() throws Exception {
        DateTime offset = DateTime.now().offset(DateField.SECOND, 30);//未来30秒
        List<SecondOrder> timeOutOrderIds = newSecondCollectionCommonService.getPreTimeOutOrderIds(offset);
        timeOutOrderIds.forEach(secondOrder -> {
            try{
                long delayInSeconds = calculateDelayInSeconds(secondOrder.getCloseTime());
                executor.schedule(() -> newSecondCollectionCommonService.cancelOrderById(secondOrder.getId()), delayInSeconds, TimeUnit.SECONDS);
            }catch (Exception e){
                log.error("二级关闭订单失败:",e);
            }
        });
    }

    /**
     * 关闭超时订单
     *
     * @throws Exception
     */
    @XxlJob("closeTimeOutSecondEquityOrder")
    public void closeTimeOutSecondEquityOrder() throws Exception {
        DateTime offset = DateTime.now().offset(DateField.SECOND, 30);//未来30秒
        List<SecondEquityPropsOrder> timeOutOrderIds = secondEquityPropsOrderService.getPreTimeOutOrderIds(offset);
        timeOutOrderIds.forEach(secondEquityPropsOrder -> {
            try{
                long delayInSeconds = calculateDelayInSeconds(secondEquityPropsOrder.getCloseTime());
                executor.schedule(() -> secondEquityPropsOrderService.cancelOrder(secondEquityPropsOrder), delayInSeconds, TimeUnit.SECONDS);
            }catch (Exception e){
                log.error("二级关闭订单失败:",e);
            }
        });
    }




    private long calculateDelayInSeconds(Date completeTime) {
        long currentTime = System.currentTimeMillis();
        long targetTime = completeTime.getTime();
        return (targetTime - currentTime) / 1000; // 转换为秒
    }

    /**
     * 二级订单结算
     *
     * @throws Exception
     */
    @XxlJob("directPushIncome")
    public void directPushIncome() throws Exception {
        List<SecondOrder> listByStatusAndIsIncome = secondOrderDao.getListByStatusAndIsIncome();
        for ( SecondOrder secondOrder: listByStatusAndIsIncome) {
            secondOrderService.extracted(secondOrder);
        }
        List<SecondEquityPropsOrder> waitSettleOrders = secondEquityPropsOrderDao.getWaitSettleOrders();
        waitSettleOrders.forEach(secondEquityPropsOrderService::extracted);
        List<BusinessCardOrder> waitSettleOrder = businessCardOrderDao.getWaitSettleOrder();
        for (BusinessCardOrder order: waitSettleOrder) {
            businessCardOrderDao.waitSettleOrder(order);
        }
        List<CollectiveOrder> waitSettleCollectiveOrder = collectiveOrderDao.getWaitSettleOrder();
        waitSettleCollectiveOrder.forEach(collectiveOrderService::extracted);
        // 交易池订单结算
        List<TradingPoolOrder> tradingPoolOrders = tradingPoolOrderDao.getWaitSettleOrder();
        tradingPoolOrders.forEach(orderSettleService::waitSettleOrder);
    }

    /**
     * 结算订单结算-杉德
     */
    @XxlJob("sandSettle")
    public void sandSettle(){
        List<OrderSettle> orderSettles = orderSettleService.getUnSettle(PayChannelEnum.SAND);
        orderSettles.forEach(orderSettleService::settleConfirm);
    }


    /**
     * 结算订单结算-连连
     */
    @XxlJob("LlPaySettle")
    public void LlPaySettle(){
        List<OrderSettle> orderSettles = orderSettleService.getUnSettle(PayChannelEnum.LL_PAY);
        orderSettles.forEach(orderSettleService::settleConfirm);
    }
}
